package com.csw.android.agorademo.ui.video_call

import android.Manifest
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import com.csw.android.agorademo.R
import com.csw.android.agorademo.databinding.UiVideoCallBinding
import com.csw.android.dev_utils.ex.FragmentEx.getAppCompatActivity
import com.csw.android.dev_utils.ex.ViewEx.setOnClickListener
import com.csw.android.dev_utils.ui.databinding.DataBindingFragment
import com.csw.android.dev_utils.utils.ToastUtils
import io.agora.rtc.IRtcEngineEventHandler
import io.agora.rtc.RtcEngine
import io.agora.rtc.video.VideoCanvas

/**
 * [视频通话示例](https://docs.agora.io/cn/Video/start_call_android?platform=Android)
 */
class VideoCallFragment : DataBindingFragment<UiVideoCallBinding>() {
    private val permissions = arrayOf(
        Manifest.permission.RECORD_AUDIO,
        Manifest.permission.CAMERA
    )
    private val requestPermissions =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
            var allGranted = true
            permissions.forEach {
                if (result?.get(it) != true) {
                    allGranted = false
                }
            }
            if (allGranted) {
                initAgoraEngineAndJoinChannel()
            } else {
                ToastUtils.showShort("权限被拒绝")
            }
        }

    private var mRtcEngine: RtcEngine? = null
    private val mRtcEventHandler = object : IRtcEngineEventHandler() {

        override fun onUserJoined(uid: Int, elapsed: Int) {
            super.onUserJoined(uid, elapsed)
            dataBinding?.mute?.post {
                ToastUtils.showShort("用户：$uid 进入房间")
            }
            //进入房间后，已在房间的一对一视频通话对象id会回调
            setupRemoteView(uid)
        }

        override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) {
            super.onJoinChannelSuccess(channel, uid, elapsed)
            dataBinding?.mute?.post {
                ToastUtils.showShort("用户：$uid 加入 $channel")
            }
        }

        // 注册 onUserOffline 回调。远端用户离开频道后，会触发该回调。
        override fun onUserOffline(uid: Int, reason: Int) {
            dataBinding?.mute?.post {
                ToastUtils.showShort("用户：$uid 已离开房间")
            }
        }

        // 注册 onUserMuteAudio 回调。远端用户静音后，会触发该回调。
        override fun onUserMuteAudio(uid: Int, muted: Boolean) {
            dataBinding?.mute?.post {
                ToastUtils.showShort("用户：$uid ${if (muted) "开启" else "关闭"}静音")
            }
        }
    }

    override fun getContentViewID() = R.layout.ui_video_call

    override fun initView(rootView: View, savedInstanceState: Bundle?) {
        super.initView(rootView, savedInstanceState)
        dataBinding?.run {
            getAppCompatActivity()?.setSupportActionBar(devUtilsToolbar)
            //直播或视频通话，默认为打开外放
            speaker.isSelected = true
        }
    }

    override fun initListener() {
        super.initListener()
        dataBinding?.run {
            devUtilsToolbar.setNavigationOnClickListener {
                activity?.finish()
            }
            listOf(
                mute,
                speaker,
                endCall,
            ).setOnClickListener {
                when (it.id) {
                    R.id.mute -> {
                        it.isSelected = !it.isSelected
                        mRtcEngine?.muteLocalAudioStream(it.isSelected)
                    }
                    R.id.speaker -> {
                        //纯音频通话，默认音频输出为听筒
                        it.isSelected = !it.isSelected
                        mRtcEngine?.setEnableSpeakerphone(it.isSelected)
                    }
                    R.id.endCall -> {
                        activity?.finish()
                    }
                }
            }
        }
    }

    override fun initData() {
        super.initData()
        requestPermissions.launch(permissions)
    }

    override fun onDestroyView() {
        //离开房间
        mRtcEngine?.leaveChannel()
        RtcEngine.destroy()
        super.onDestroyView()
    }

    private fun initAgoraEngineAndJoinChannel() {
        initializeAgoraEngine()
        setupLocalVideo()
        joinChannel()
    }

    // 调用 Agora SDK 的方法初始化 RtcEngine。
    private fun initializeAgoraEngine() {
        context?.run {
            try {
                mRtcEngine =
                    RtcEngine.create(this, getString(R.string.agora_app_id), mRtcEventHandler)
            } catch (e: Exception) {
                e.printStackTrace()
                throw RuntimeException(
                    "NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(
                        e
                    )
                )
            }
        }
    }

    private fun setupLocalVideo() {
        // 启用视频模块。
        mRtcEngine?.run {
            enableVideo()
            dataBinding?.cameraPreview?.run {
                // 创建 SurfaceView。
                val surfaceView = RtcEngine.CreateRendererView(context)
                surfaceView.setZOrderMediaOverlay(true)
                addView(surfaceView)
                // 设置本地视图。
                setupLocalVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, 0))
            }
        }
    }

    /**
     * 设置远程用户视图渲染
     */
    private fun setupRemoteView(uid: Int) {
        mRtcEngine?.run {
            dataBinding?.remotePreview?.run {
                val surfaceView = RtcEngine.CreateRendererView(context)
                addView(surfaceView)
                // 设置远程视图。
                setupRemoteVideo(VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_FIT, uid))
            }
        }
    }

    private fun joinChannel() {
        // 此处token由agora开发平台生成的临时token，一天就过期，正式运营应该使用后台返回的token
        // 调用 Agora SDK 的 joinChannel 方法加入频道。未指定 uid，SDK 会自动分配一个。
        mRtcEngine?.joinChannel(
            getString(R.string.agora_access_token),
            "voiceDemoChannel1",
            "Extra Optional Data",
            0
        )
    }
}